package com.zhichat.web.socket;

import com.alibaba.fastjson.JSON;
import com.zhichat.infrastructure.Enums.ContactTypeEnum;
import com.zhichat.infrastructure.Enums.MsgTypeEnum;
import com.zhichat.infrastructure.exception.http.CommonException;
import com.zhichat.infrastructure.redis.Keys;
import com.zhichat.infrastructure.redis.RedisRepository;
import com.zhichat.infrastructure.redis.rediskey.ZhiChat;
import com.zhichat.infrastructure.util.ThreadLocalCache;
import com.zhichat.web.vo.ws.MsgVO;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.CharsetUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @ClassName: GlobalMsgHandle
 * @Description: 全局 redisson topic 消息处理器
 * @Author: 团长九哥 https://space.bilibili.com/602197686
 * @CreateDate: 2024/12/13 11:08
 */
@Slf4j
@Component
@AllArgsConstructor
public class GlobalMsgHandle {

    private final RedissonClient redissonClient;
    private final ChannelContextCommon channelContextCommon;
    private final RedisRepository redisRepository;

    /**
     * 发送消息 -> redisson topic
     */
    public <T> void sendHandler(MsgVO<T> msg) {
        redissonClient.getTopic(Keys.REDISSON_TOPIC_CHAT_MESSAGE_KEY).publish(msg);
    }

    /**
     * 发送消息 - > channel
     */
    public <T> void sendMessageToUserChannel(MsgVO<T> msg, Long receiverId) {
        // 获取接收人的channel
        Channel receiverChannel = channelContextCommon.getUserChannel(receiverId);
        if (Objects.isNull(receiverChannel)) return;
        // 是否需要这么转换呢？？？
//        msg.setReceiverId(msg.getSenderId());
//        msg.setReceiverNickName(msg.getSenderNickName());
        System.out.println("发送消息：" + JSON.toJSONString(msg));
        receiverChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(msg)));
    }

    /**
     * 发送消息
     */
    public <T> void sendMessage(MsgVO<T> msg) {
        Integer receiverType = msg.getReceiverType();
        Long receiverId = msg.getReceiverId();
        if (Objects.equals(ContactTypeEnum.USER.getCode(), receiverType)) {
            sendMessageToUserChannel(msg, receiverId);
            // 强制下线
            if (Objects.equals(MsgTypeEnum.FORCE_OFFLINE.getCode(), msg.getMsgType())) {
                closeChannel(receiverId);
            }
        } else if (Objects.equals(ContactTypeEnum.GROUP.getCode(), receiverType)) {
            ChannelGroup channelGroup = channelContextCommon.getChannelGroup(receiverId);
            if (Objects.isNull(channelGroup)) return;
            channelGroup.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(msg)));
            // 解散群组
            if (Objects.equals(MsgTypeEnum.GROUP_DISMISS.getCode(), msg.getMsgType())) {
                channelContextCommon.removeGroupChannel(receiverId);
            }
        } else {
            throw CommonException.PARAMETER_COMMON_EXCEPTION;
        }
    }

    /**
     * 用户下线
     */
    public void closeChannel(Long userId) {
        channelContextCommon.removeUserChannel(userId);
        redisRepository.del(new ZhiChat(Keys.TOKEN), ThreadLocalCache.getUserId());
    }
}
